package org.jhh.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.BaseCodec;
import org.redisson.client.protocol.Decoder;
import org.redisson.client.protocol.Encoder;
import org.redisson.config.Config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
@EnableConfigurationProperties(RedisClientConfigProperties.class)
public class RedisClientConfig {

    @Bean("redissonClient")
    public RedissonClient redissonClient(RedisClientConfigProperties properties) {
        Config config = new Config();
        config.setCodec(new RedisCodec());

        config.useSingleServer()
                .setAddress("redis://" + properties.getHost() + ":" + properties.getPort())
                .setPassword(properties.getPassword())
                .setConnectionPoolSize(properties.getPoolSize())
                .setConnectionMinimumIdleSize(properties.getMinIdleSize())
                .setIdleConnectionTimeout(properties.getIdleTimeout())
                .setConnectTimeout(properties.getConnectTimeout())
                .setRetryAttempts(properties.getRetryAttempts())
                .setRetryInterval(properties.getRetryInterval())
                .setPingConnectionInterval(properties.getPingInterval())
                .setKeepAlive(properties.isKeepAlive())
        ;

        return Redisson.create(config);
    }

    static class RedisCodec extends BaseCodec {
        // 适配FastJSON 1.x的序列化器配置
        private final Encoder encoder = in -> {
            ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
            try (ByteBufOutputStream os = new ByteBufOutputStream(out)) {
                // 移除FastJSON 1.x不支持的WriteGenericType，保留兼容特性
                JSON.writeJSONString(
                        os,
                        in,
                        SerializerFeature.WriteClassName,          // 保留类名（1.x支持）
                        SerializerFeature.WriteMapNullValue,       // 保留空Map（1.x支持）
                        SerializerFeature.DisableCircularReferenceDetect  // 禁用循环引用（1.x支持）
                );
                return os.buffer();
            } catch (IOException e) {
                out.release();
                throw e;
            } catch (Exception e) {
                out.release();
                throw new IOException("序列化失败: " + e.getMessage(), e);
            }
        };

        // 适配FastJSON 1.x的反序列化器配置
        private final Decoder<Object> decoder = (buf, state) -> {
            try (ByteBufInputStream is = new ByteBufInputStream(buf)) {
                return JSON.parseObject(
                        is,
                        Object.class,
                        Feature.SupportAutoType,        // 支持自动类型（1.x需开启）
                        Feature.IgnoreNotMatch,         // 忽略不匹配字段（1.x支持）
                        Feature.UseBigDecimal           // 数值类型处理（1.x支持）
                );
            } catch (Exception e) {
                throw new RuntimeException("反序列化失败: " + e.getMessage(), e);
            }
        };

        @Override
        public Decoder<Object> getValueDecoder() {
            return decoder;
        }

        @Override
        public Encoder getValueEncoder() {
            return encoder;
        }
    }
}
